package com.qjc.demo.thread.threadlocal;

/**
 * @Description: ThreadLocal不可继承，也就是说在主线程中设置值，在子线程中是获取不到的，
 * 但是有一个可继承的ThreadLocal，叫InheritableThreadLocal
 * @Author: qjc
 * @Date: 2020/7/17
 */
public class ThreadLocalDemo {

    //(1)print函数
    static void print(String str) {
        //1.1 打印当前线程本地内存中localVariable变量的值
        System.out.println(str + ":" + localVariable.get());
        //1.2 清除当前线程本地内存中的 localVariable 变量
//        localVariable.remove();
    }

    //（2）创建ThreadLocal变量
    static ThreadLocal<String> localVariable = new ThreadLocal<>();

    public static void main(String[] args) {
        //(3)创建线程One
        Thread threadOne = new Thread(() -> {
            try {
                //3.1 设置线程One 中本地变量 localVariable 的值
                localVariable.set("threadOne local variable");
                //3.2 调用打印函数
                print("threadOne");
                //3.3 打印本地变量值
                System.out.println("threadOne remove after" + ":" + localVariable.get());
            } finally {
                /**
                 * 必须回收自定义的ThreadLocal变量，尤其在线程池场景下，线程经常会被复用，
                 * 如果不清理自定义的 ThreadLocal变量，可能会影响后续业务逻辑和造成内存泄露等问题。
                 * 尽量在代理中使用try-finally块进行回收。
                 */
                localVariable.remove();
            }
        });

        //(4)创建线程Two
        Thread threadTwo = new Thread(() -> {
            try {
                //4.1 设置线程One 中本地变量 localVariable 的值
                localVariable.set("threadTwo local variable");
                //4.2 调用打印函数
                print("threadTwo");
                //4.3 打印本地变量值
                System.out.println("threadTwo remove after" + ":" + localVariable.get());
            } finally {
                localVariable.remove();
            }
        });
        //(5) 启动线程
        threadOne.start();
        threadTwo.start();

    }

}
